package com.wangbo.box.visitor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class VisitorPattern {

    interface Visitor {
        void visit(ElementA element);

        void visit(ElementB element);
    }

    static class VisitorA implements Visitor {
        public void visit(ElementA element) {
            System.out.println("具体访问者A访问-->" + element.operationA());
        }

        public void visit(ElementB element) {
            System.out.println("具体访问者A访问-->" + element.operationB());
        }
    }

    static class VisitorB implements Visitor {
        public void visit(ElementA element) {
            System.out.println("具体访问者B访问-->" + element.operationA());
        }

        public void visit(ElementB element) {
            System.out.println("具体访问者B访问-->" + element.operationB());
        }
    }

    //抽象元素类
    interface Element {
        void accept(Visitor visitor);
    }

    //具体元素A类
    static class ElementA implements Element {
        public void accept(Visitor visitor) {
            visitor.visit(this);
        }

        public String operationA() {
            return "具体元素A的操作。";
        }
    }

    //具体元素B类
    static class ElementB implements Element {
        public void accept(Visitor visitor) {
            visitor.visit(this);
        }

        public String operationB() {
            return "具体元素B的操作。";
        }
    }

    //对象结构角色
    static class ObjectStructure {
        private List<Element> list = new ArrayList<>();

        public void accept(Visitor visitor) {
            Iterator<Element> i = list.iterator();
            while (i.hasNext()) {
                i.next().accept(visitor);
            }
        }

        public void add(Element element) {
            list.add(element);
        }

        public void remove(Element element) {
            list.remove(element);
        }
    }

    public static void main(String[] args) {
        ObjectStructure os = new ObjectStructure();
        os.add(new ElementA());
        os.add(new ElementB());
        Visitor visitor = new VisitorA();
        os.accept(visitor);
        System.out.println("------------------------");
        visitor = new VisitorB();
        os.accept(visitor);
    }
}
